/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-01-19     wanghaijing  the first version
 */

 #include <rtthread.h>
 #include <rtdevice.h>
 #include <board.h>
 #include <dev_spi_flash.h>
 #include <drv_qspi.h>
 #include "dev_spi_flash_sfud.h"
 #include <dfs_fs.h>
 
 #define SPI_BUS_NAME "qspi2"
 #define SPI_DEVICE_NAME "qspi20"
 #define SPI_FLASH_DEVICE_NAME "W25Q64Q"
 
 static void cs_pin_control(uint32_t cs)
 {
     board_write_spi_cs(BOARD_SPI_CS_PIN, cs); 
 }
 
 
 char w25qxx_read_status_register2(struct rt_qspi_device *device)
 {
     /* 0x35 read status register2 */
     char instruction = 0x35, status;
 
     rt_qspi_send_then_recv(device, &instruction, 1, &status, 1);
 
     return status;
 }
 
 void w25qxx_write_enable(struct rt_qspi_device *device)
 {
     /* 0x06 write enable */
     char instruction = 0x06;
 
     rt_qspi_send(device, &instruction, 1);
 }
 
 void w25qxx_enter_qspi_mode(struct rt_qspi_device *device)
 {
     char status = 0;
     /* 0x38 enter qspi mode */
     char instruction = 0x38;
     char write_status2_buf[2] = {0};
 
     /* 0x31 write status register2 */
     write_status2_buf[0] = 0x31;
 
     status = w25qxx_read_status_register2(device);
     if (!(status & 0x02))
     {
         status |= 1 << 1;
         w25qxx_write_enable(device);
         write_status2_buf[1] = status;
         rt_qspi_send(device, &write_status2_buf, 2);
         rt_qspi_send(device, &instruction, 1);
         rt_kprintf("flash already enter qspi mode\n");
         rt_thread_mdelay(10);
     }
 }
 
 static int rt_qspi_flash_init(void)
 {
     extern rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name);
 
     rt_hw_qspi_device_attach(SPI_BUS_NAME, SPI_DEVICE_NAME, RT_NULL, 1, RT_NULL, RT_NULL, cs_pin_control);
     RT_ASSERT(rt_sfud_flash_probe(SPI_FLASH_DEVICE_NAME, SPI_DEVICE_NAME)!=RT_NULL);
 
     #ifdef BSP_USING_FATFS_ROOTFS
     int try=10;
     while(dfs_mount(SPI_FLASH_DEVICE_NAME, "/spi", "elm", 0, 0) != 0)
     {
         rt_kprintf("mount to '/spi' failed! try again...\n");
 
         rt_thread_mdelay(100);
         try--;
         if(try<=0) break;
     }
     rt_kprintf("mount to '/spi' success!\n");
     #endif
 
     return RT_EOK;
 }
 INIT_APP_EXPORT(rt_qspi_flash_init);
 